package com.promise.jokerdream.work.manager

import com.promise.jokerdream.work.IWork
import com.promise.jokerdream.work.WorkFactory
import com.promise.jokerdream.database.UserDataManager
import com.promise.jokerdream.database.account.UserAccount
import com.promise.jokerdream.utils.AppContext
import com.promise.jokerdream.repository.PhoneGameApi
import com.promise.jokerdream.database.entity.TimerTaskConfigEntity
import kotlinx.coroutines.*
import java.time.LocalDateTime
import java.time.LocalTime
import java.time.temporal.ChronoUnit
import java.util.concurrent.atomic.AtomicBoolean

/**
 * 定时器工作管理器
 * 负责每分钟执行定时任务，整点时执行额外的任务列表
 * 使用独立的协程作用域，避免被其他组件取消
 */
open class TimerWorkManager private constructor() {

    companion object {
        @Volatile
        private var INSTANCE: TimerWorkManager? = null

        /**
         * 获取TimerWorkManager单例
         */
        fun getInstance(): TimerWorkManager {
            return INSTANCE ?: synchronized(this) {
                INSTANCE ?: TimerWorkManager().also { INSTANCE = it }
            }
        }
    }

    // 独立的协程作用域，避免被其他组件取消
    private val timerScope: CoroutineScope by lazy {
        CoroutineScope(SupervisorJob() + Dispatchers.Default)
    }
    
    // 定时器是否已启动
    private val isTimerStarted = AtomicBoolean(false)
    
    // 当前运行的定时器协程
    private var timerJob: Job? = null
    
    // 使用CommonWorkManager来执行任务
    private val workManager = CommonWorkManager.getInstance()
    
    // 用户数据管理器，用于实时获取用户信息
    private val userDataManager by lazy { UserDataManager.getInstance(AppContext.get()) }
    
    // 手机端游戏API，用于查询活动信息
    private val phoneGameApi by lazy { PhoneGameApi.getInstance() }

    /**
     * 获取当前用户账户信息
     */
    private fun getCurrentUserAccount(): UserAccount? {
        return userDataManager.getCurrentAccount()
    }

    /**
     * 获取每分钟任务列表
     * 从WorkFactory的createScheduledWorks方法获取
     * 实时获取最新的用户配置
     */
    protected open suspend fun getMinutelyWorkList(): List<IWork> {
        val currentAccount = getCurrentUserAccount()
        
        return if (currentAccount != null) {
            WorkFactory.createScheduledWorks(currentAccount.userId, currentAccount.config)
        } else {
            emptyList()
        }
    }

    /**
     * 过滤活动类工作
     * 根据当前可用的活动列表过滤掉不可用的活动类工作
     */
    private suspend fun filterActWorks(works: List<IWork>): List<IWork> {
        // 查询最新活动信息
        val latestActResult = phoneGameApi.queryLatestActData()
        val availableActList = latestActResult.getOrNull()?.actList ?: emptyList()
        
        // 过滤活动类工作
        return works.filter { work ->
            if (work.isActWork) {
                // 如果活动列表为空，不过滤任何活动类工作
                if (availableActList.isEmpty()) {
                    true
                } else {
                    // 检查活动类工作是否在活动列表中
                    val isActAvailable = availableActList.any { actName ->
                        actName.contains(work.name, ignoreCase = true)
                    }
                    isActAvailable
                }
            } else {
                true
            }
        }
    }

    /**
     * 获取整点任务列表
     * 从WorkFactory的createRewardWorks方法获取
     * 实时获取最新的用户配置
     */
    protected open suspend fun getHourlyWorkList(): List<IWork> {
        val currentAccount = getCurrentUserAccount()
        
        return if (currentAccount != null) {
            WorkFactory.createRewardWorks(currentAccount.userId, currentAccount.config)
        } else {
            emptyList()
        }
    }

    /**
     * 启动定时器
     */
    fun startTimer() {
        if (isTimerStarted.compareAndSet(false, true)) {
            timerJob = timerScope.launch {
                while (isActive) {
                    try {
                        // 计算到下一个整分钟的时间
                        val nextMinuteTime = calculateNextMinuteTime()
                        val delayMillis = ChronoUnit.MILLIS.between(LocalDateTime.now(), nextMinuteTime)
                        
                        println("定时器等待到下一个整分钟: $nextMinuteTime, 等待时间: ${delayMillis}ms")
                        
                        // 等待到下一个整分钟
                        delay(delayMillis)
                        
                        // 执行定时任务
                        executeScheduledTasks()
                        
                    } catch (e: Exception) {
                        if (e is CancellationException) {
                            println("定时器被取消")
                            break
                        } else {
                            println("定时器执行异常: ${e.message}")
                            // 异常后等待10秒再重试
                            delay(10_000)
                        }
                    }
                }
            }
        }
    }

    /**
     * 停止定时器
     */
    fun stopTimer() {
        isTimerStarted.set(false)
        timerJob?.cancel()
        timerJob = null
    }

    /**
     * 计算下一个整分钟时间
     */
    private fun calculateNextMinuteTime(): LocalDateTime {
        val now = LocalDateTime.now()
        val nextMinute = now.plusMinutes(1)
            .withSecond(0)
            .withNano(0)
        return nextMinute
    }

    /**
     * 执行定时任务
     */
    private suspend fun executeScheduledTasks() {
        val now = LocalDateTime.now()
        
        println("执行定时任务 - 当前时间: $now")
        
        // 获取当前用户账户
        val currentAccount = getCurrentUserAccount()
        if (currentAccount == null) {
            println("未找到当前用户账户，跳过定时任务执行")
            return
        }
        
        // 获取定时任务配置
        val timerTaskConfigs = currentAccount.config.timerTaskConfig
        println("获取到 ${timerTaskConfigs.size} 个定时任务配置")
        
        // 检查并执行定时任务
        val tasksToExecute = mutableListOf<TimerTaskConfigEntity>()
        for (taskConfig in timerTaskConfigs) {
            if (shouldExecuteTimerTask(taskConfig, now)) {
                tasksToExecute.add(taskConfig)
                println("定时任务 ${taskConfig.taskName} 符合执行条件")
            }
        }
        
        // 获取每分钟任务列表
        val minutelyWorks = getMinutelyWorkList()
        println("获取到 ${minutelyWorks.size} 个每分钟任务")
        
        // 判断是否需要执行hourlyWorks
        // 条件：now.minute <= 10 且上次执行hourlyWorks的时间跟当前的hour不一样
        val shouldExecuteHourlyWorks = shouldExecuteHourlyWorks(currentAccount, now)
        val hourlyWorks = if (shouldExecuteHourlyWorks) {
            println("符合hourlyWorks执行条件，获取整点任务列表")
            getHourlyWorkList()
        } else {
            emptyList()
        }
        println("获取到 ${hourlyWorks.size} 个整点任务")
        
        // 如果有定时任务符合条件，添加所有createWorks的工作
        val timerWorks = if (tasksToExecute.isNotEmpty()) {
            println("定时任务符合条件，添加所有createWorks工作")
            WorkFactory.createWorks(currentAccount.userId, currentAccount.config)
        } else {
            emptyList()
        }
        println("获取到 ${timerWorks.size} 个定时任务工作")
        
        // 合并所有任务列表并去重
        val mergedWorks = mergeAndDeduplicateWorks(minutelyWorks, hourlyWorks, timerWorks)
        println("去重后共有 ${mergedWorks.size} 个任务")
        
        // 过滤活动类工作
        val allWorks = filterActWorks(mergedWorks)
        println("过滤后共有 ${allWorks.size} 个任务需要执行")
        
        // 将任务添加到CommonWorkManager的工作队列
        if (allWorks.isNotEmpty()) {
            workManager.addWorks(allWorks)
        }
        
        // 更新已执行的定时任务状态
        if (tasksToExecute.isNotEmpty()) {
            updateExecutedTimerTasks(currentAccount, tasksToExecute, now)
        }
        
        // 更新hourlyWorks的执行时间
        if (shouldExecuteHourlyWorks) {
            updateHourlyWorkExecutedTime(currentAccount, now)
        }
    }

    /**
     * 判断是否需要执行hourlyWorks
     * 条件：now.minute <= 10 且上次执行hourlyWorks的时间跟当前的hour不一样
     */
    private fun shouldExecuteHourlyWorks(account: UserAccount, now: LocalDateTime): Boolean {
        // 检查分钟数是否 <= 10
        if (now.minute > 10) {
            return false
        }
        
        // 获取上次执行时间
        val lastExecutedTimeStr = account.config.lastHourlyWorkExecutedTime
        if (lastExecutedTimeStr == null) {
            // 如果没有上次执行时间，则执行
            return true
        }
        
        // 解析上次执行时间
        try {
            val lastExecutedTime = LocalDateTime.parse(lastExecutedTimeStr)
            // 比较上次执行时间的hour和当前时间的hour
            val lastHour = lastExecutedTime.hour
            val currentHour = now.hour
            
            // 如果hour不一样，则执行
            return lastHour != currentHour
        } catch (e: Exception) {
            println("解析上次执行hourlyWorks时间失败: ${e.message}")
            return false
        }
    }
    
    /**
     * 更新hourlyWorks的执行时间
     */
    private suspend fun updateHourlyWorkExecutedTime(account: UserAccount, now: LocalDateTime) {
        try {
            val updatedConfig = account.config.copy(
                lastHourlyWorkExecutedTime = now.toString()
            )
            val updatedAccount = account.copy(config = updatedConfig)
            userDataManager.saveUserAccount(updatedAccount)
            
            println("已更新hourlyWorks执行时间: ${now}")
        } catch (e: Exception) {
            println("更新hourlyWorks执行时间失败: ${e.message}")
        }
    }
    
    /**
     * 判断定时任务是否应该执行
     * 检查条件：1. 任务已启用 2. 当前时间在时间范围内 3. 今天未执行过
     */
    private fun shouldExecuteTimerTask(taskConfig: TimerTaskConfigEntity, now: LocalDateTime): Boolean {
        // 检查任务是否启用
        if (!taskConfig.isEnabled) {
            return false
        }
        
        // 检查今天是否已执行
        if (taskConfig.isTodayExecuted()) {
            return false
        }
        
        // 检查当前时间是否在任务时间范围内
        val currentTime = now.toLocalTime()
        val startTime = LocalTime.parse(taskConfig.startTime)
        val endTime = LocalTime.parse(taskConfig.endTime)
        
        return if (startTime <= endTime) {
            // 同一天内的时间范围
            currentTime >= startTime && currentTime <= endTime
        } else {
            // 跨天的时间范围（如 22:00-06:00）
            currentTime >= startTime || currentTime <= endTime
        }
    }
    
    /**
     * 更新已执行的定时任务状态
     */
    private suspend fun updateExecutedTimerTasks(
        account: UserAccount,
        executedTasks: List<TimerTaskConfigEntity>,
        now: LocalDateTime
    ) {
        try {
            // 直接使用当前日期，让TimerTaskConfig自己处理游戏日期逻辑
            val currentDate = now.toLocalDate().toString()
            
            val updatedTimerTaskConfig = account.config.timerTaskConfig.map { taskConfig ->
                if (executedTasks.any { it.taskId == taskConfig.taskId }) {
                    taskConfig.copy(lastExecutedDate = currentDate)
                } else {
                    taskConfig
                }
            }
            
            val updatedConfig = account.config.copy(timerTaskConfig = updatedTimerTaskConfig)
            val updatedAccount = account.copy(config = updatedConfig)
            userDataManager.saveUserAccount(updatedAccount)
            
            println("已更新 ${executedTasks.size} 个定时任务的执行状态")
        } catch (e: Exception) {
            println("更新定时任务执行状态失败: ${e.message}")
        }
    }

    /**
     * 合并任务列表并去重
     * 去重规则：相同name和uin的任务视为重复
     */
    private fun mergeAndDeduplicateWorks(
        minutelyWorks: List<IWork>,
        hourlyWorks: List<IWork>,
        timerWorks: List<IWork>
    ): List<IWork> {
        val workMap = mutableMapOf<String, IWork>()
        
        // 先添加每分钟任务
        minutelyWorks.forEach { work ->
            val key = "${work.name}_${work.uin}"
            workMap[key] = work
        }
        
        // 再添加整点任务（会覆盖同名的每分钟任务）
        hourlyWorks.forEach { work ->
            val key = "${work.name}_${work.uin}"
            workMap[key] = work
        }
        
        // 最后添加定时任务（会覆盖同名的其他任务）
        timerWorks.forEach { work ->
            val key = "${work.name}_${work.uin}"
            workMap[key] = work
        }
        
        return workMap.values.toList()
    }

    /**
     * 销毁管理器
     */
    fun destroy() {
        stopTimer()
        timerScope.cancel()
    }
}
